/*
 * table_Linkage.c
 *
 *  Created on: 2012/03/29
 *      Author: guanxiaoying
 */
#include "../../parser/coredef.h"


/*KIND_LINKAGE*/
typedef struct _LINKAGE
{
	 UCHAR bExternal;
	 UCHAR bReferred;
	 AST  astDel;  /* 2 */
	 AST  astTen;  /*3 */
	 AST  astAll; /*4 */
	 AST  astSym; /*4 */
	 RBTREE rbtree;
} CCLINKAGE, *PCCLINKAGE;

static AST      gblCcLinkage=0;

#define TableSize  (sizeof(CCLINKAGE))
#define TableType  PCCLINKAGE
#define stTable stCcLinkageManager.memoryBlocks
#define maxTable stCcLinkageManager.maxRecordNum
#define  maxNumPerBlk  (stCcLinkageManager.astMaxNum_Block)

static TABLEMANAGER stCcLinkageManager = {
//		U4                  usIdx;
		0,
//		PSZ				    con_pszName;    constant
		__FILE__,
//		U2					con_usSize;		constant
		TableSize,
//		U2					block_num;	　　　　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_Block;     １回設定のみ
		0,
//		S4					astTabNum_LastPage; 　　　　Reset clear  際　要
		0,
//		S4					astMaxNum_LastPage;     Reset clear  際　要
		0,
//		U4					ulMaxByte;	　　　　　　　　　　クリアしない
		0,
//		U4					con_minPageSize;　　　　　　　　　　constant
		0
};
static VOID resetListener( U4  procid, U2 index )
{
	if( procid == stCcLinkageManager.u4Idx )
	{
		if( index > 0 && index < MAX_VOLUMN_OF_TABLE )
		{
			stTable[ index-1] = NULL;
		}
	}

}
static TableType core_getTable( AST index )
{
	TableType temp = (TableType)Check_Com( &stCcLinkageManager, resetListener, index );
	if( temp != NULL ){ return &temp[index%maxNumPerBlk]; } return NULL;
}


static BOOL ClearTable( VOID )
{
	gblCcLinkage = 0;
	return Clear_Com( &stCcLinkageManager );
}
static BOOL ResetTable( VOID )
{
	gblCcLinkage = 0;
	return Reset_Com( &stCcLinkageManager );
}
static BOOL AllocTable( AST astReqArg )
{
	return AllocTable_Com( &stCcLinkageManager, astReqArg, resetListener );
}
static AST getMaxLineNum( VOID ){
	return maxTable;
}
/* give up the way that defining get/set function pointer in the struct,
 * because of memory volume.
 */
static BOOL  isExternal( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->bExternal;
}
/* set method */
static BOOL  setExternal( AST index, BOOL value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->bExternal = value;
}
//	IDX_DECSYMCHAIN
/*  get method */
static AST  getDefinition( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astDel;
}
/* set method */
static AST  setDefinition( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->astDel = idx;
}
//	IDX_TENSYMCHAIN
/*  get method */
static AST  getTenDecl( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astTen;
}
/* set method */
static AST  setTenDecl( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->astTen = idx;
}
//	IDX_ALLSYMCHAIN
/*  get method */
static AST  getAll( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astAll;
}
/* set method */
static AST  setAll( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->astAll = idx;
}
//	IDX_REFERRED
/*  get method */
static BOOL  isReferInfo( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->bReferred;
}
/* set method */
static BOOL  setReferInfo( AST index, BOOL v )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->bReferred = v;
}
static AST  getDefinedSym( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->astSym;
}
/* set method */
static AST  setDefinedSym( AST index, AST idx )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		assert_index( maxTable, index, idx );
		return 0;
	}
	return pTbl->astSym = idx;
}
static AST getLeft( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild;
}
static AST setLeft( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astLeftChild = value;
}
static AST getRight( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild;
}
static AST setRight( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astRightChild = value;
}
static AST getParent( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent;
}
static AST setParent( AST index, AST value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.astParent = value;
}
static AST getIndex( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return stUniteChainAccess.parameter_sym.get( pTbl->astAll );
}
static U2 getColor( AST index )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor;
}
static U2 setColor( AST index, U2 value )
{
	TableType pTbl = core_getTable( index );
	if( pTbl == NULL )
	{
		return 0;
	}
	return pTbl->rbtree.lColor = value;
}
static ACCESS_RBTREE stAccessRbtree =
{
		AllocTable,
		getMaxLineNum,
		getIndex,
		{
				getLeft,
				setLeft
		},
		{
				getRight,
				setRight
		},
		{
				getParent,
				setParent
		},
		{
				getColor,
				setColor
		}
};
static S4  cmpSymbolName( AST astSymbol, void * pstrName )
{
	PSZ  pszDefinedName;
	PSZ  pszNewName;
	S4 ret;

	pszNewName = ( PSZ )pstrName;
	if( pszNewName == NULL )
	{
		return RBT_LESS;
	}
	pszDefinedName = stSymbolInfoAccess.name.get( astSymbol );
	ret = strcmp(pszDefinedName, pszNewName );
	if( ret == 0 )
	{
		return RBT_FOUND;
	}
	if( ret < 0 )
	{
		return RBT_LESS;
	}
	return RBT_LARGER;
}
static AST  findLinkage( AST astSym ){
	AST astResult;
	S4 ret;
	ret = FindData( &stAccessRbtree, gblCcLinkage, stSymbolInfoAccess.name.get( astSym ),
			&astResult, cmpSymbolName );
	if( ret == RBT_FOUND )
	{
		return astResult;
	}
	return 0;
}
static AST  addLinkage( AST astSym ){
	AST astResult;
	S4 find_result;
	AST nMaxIndex=0;
	PSZ name = stSymbolInfoAccess.name.get( astSym );
	BOOL bret;

	find_result = FindData( &stAccessRbtree, gblCcLinkage, name, &astResult, cmpSymbolName );
	if( find_result == RBT_FOUND )
	{
		return astResult;
	}
	bret =  InsertData( &stAccessRbtree, find_result, astResult, &gblCcLinkage, &nMaxIndex );
	if( bret == FALSE  )
	{
		return (0);
	}
	return nMaxIndex;
}
static VOID clearRoot( VOID ){
	gblCcLinkage = 0;
}
const CCLINKAGE_ACCESS stCCLinkageAccess = {
		ClearTable,
		ResetTable,
		AllocTable,
		getMaxLineNum,
		findLinkage,
		addLinkage,
		clearRoot,
//				ACCESS_BOOL_FIELD bExternal;
		{
				isExternal,
				setExternal
		},
//				ACCESS_IDX_FIELD definitionChain;
		{
				getDefinition,
				setDefinition
		},
//				ACCESS_IDX_FIELD tenDeclChain;
		{
				getTenDecl,
				setTenDecl
		},
//				ACCESS_IDX_FIELD allChain;
		{
				getAll,
				setAll
		},
//				ACCESS_IDX_FIELD definitionSym;

		{
				getDefinedSym,
				setDefinedSym
		},

		{
				isReferInfo,
				setReferInfo
		}
};
/* end of file */

